﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SimpleUtils;
using SimpleUtils.Win;
using System.Runtime.InteropServices;
using AgentObjects;
using System.IO;

namespace SimpleReminder
{
    public partial class frmRunAgent : Form
    {
        string _characterID;
        string _agentPath;
        short _agentTop;
        short _agentLeft;
        string _animation;
        string _speech;
        bool _closePending = false;
        static Hashtable _runningForms = new Hashtable();
        
        public static frmRunAgent GetRunningForm(string characterID) 
        {
            return _runningForms[characterID] as frmRunAgent;
        }


        public frmRunAgent(string characterID, string agentPath, short agentTop, short agentLeft, string animation, string speech)
        {
            InitializeComponent();

            _characterID = characterID;
            _agentPath = agentPath;
            _agentTop = agentTop;
            _agentLeft = agentLeft;
            _animation = animation;
            _speech = speech;
        }

        private void frmRunAgent_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (_runningForms.Contains(_characterID))
                {
                    _runningForms.Remove(_characterID);
                }
            }
            catch { }
            UnloadAgent(_characterID);
        }

        public IAgentCtlCharacterEx LoadAgent(string characterID, string agentPath, short agentTop, short agentLeft)
        {
            characterID = DateTime.Now.GetHashCode().ToString();

            if (String.IsNullOrEmpty(characterID))
                return null;
            IAgentCtlCharacterEx character = null;

            string path = agentPath;
            bool isRandom = (path == Agent.RANDOM || String.IsNullOrEmpty(path) || Convert.IsDBNull(path));
            if (isRandom)
            {
                path = Agent.GetRandomAgent();
            }

            if (path == null || !File.Exists(path))
                return null;

            UnloadAgent(characterID);
            axAgent.Characters.Load(characterID, path);
            
            character = axAgent.Characters[characterID];
            character.AutoPopupMenu = false;
            character.LanguageID = 0x409;

            if (isRandom)
            {
                agentTop = (short)Utils.GetRandomNo(Screen.PrimaryScreen.WorkingArea.Height - character.Height);
                agentLeft = (short)Utils.GetRandomNo(Screen.PrimaryScreen.WorkingArea.Width - character.Width);
            }

            character.Top = agentTop;
            character.Left = agentLeft;

            character.Show(null);

            if (character.Balloon.Enabled)
            {
                character.Balloon.FontName = "Tahoma";
                character.Balloon.FontSize = 10;
            }

            Agent.SetDefaultBallonStyle(character);
            return character;
        }

        public void UnloadAgent(string characterID)
        {
            try
            {
                IAgentCtlCharacterEx character = axAgent.Characters[characterID];
                Agent.StopCharacter(character);
                Agent.HideCharacter(character);
            }
            catch { }
            //catch (COMException ex)
            //{
            //    switch (ex.ErrorCode)
            //    {
            //        case -2147213310: //"角色 ID 无效。\n请检查是否已经定义该 ID 以及其拼写是否正确。"
            //            break;
            //        default:
            //            throw;
            //    }
            //}
            try
            {
                axAgent.Characters.Unload(characterID);
                //Application.DoEvents();
            }
            catch { }
        }

        //public void PlayAnimation(string characterID, string animation)
        //{
        //    IAgentCtlCharacterEx character = axAgent.Characters[characterID];
        //    if (character != null && !String.IsNullOrEmpty(animation))
        //    {
        //        Agent.PlayAnimation(character, animation.Split(new char[] { ';' }));
        //    }
        //}

        //public void Speak(string characterID, string speech)
        //{
        //    IAgentCtlCharacterEx character = axAgent.Characters[characterID];
        //    if (character != null && !String.IsNullOrEmpty(speech))
        //    {
        //        character.Speak(speech, null);
        //    }
        //}

        bool _inPlaying = false;
        public bool InPlaying
        {
            get
            {
                return _inPlaying;
            }
        }
        public bool ClosePending
        {
            get { return _closePending; }
            set { _closePending = value; }
        }

        private void frmRunAgent_Load(object sender, EventArgs e)
        {
            try
            {
                _inPlaying = true;
                _runningForms.Add(_characterID, this);

                IAgentCtlCharacterEx character = LoadAgent(_characterID, _agentPath, _agentTop, _agentLeft);

                if (character == null) return;

                if (String.IsNullOrEmpty(_animation))
                {
                    _animation = Agent.GetRandomAnimation(character);
                    Agent.PlayAnimation(character, _animation);
                }
                else
                {
                    Agent.PlayAnimation(character, _animation.Split(new char[] { ';' }));
                }

                if (!String.IsNullOrEmpty(_speech))
                {
#if DEBUG
                    character.Speak(String.Format("{0:yyyy-MM-dd HH:mm:ss}\n{1}", DateTime.Now, _speech), null);
#else
                character.Speak(_speech, null);
#endif
                }
            }
            catch (Exception ex)
            {
                SimpleMessage.ShowException(ex);
            }
            finally
            {
                _inPlaying = false;
            }

        }

        private void CloseForm(string characterID)
        {
            if (_inPlaying) return;
            UnloadAgent(characterID);
            this.Close();
        }

        //private bool IsLeftButtonClicked(short button)
        //{
        //    return (button & 0x0001) > 0;
        //}

        private void axAgent_ClickEvent(object sender, AxAgentObjects._AgentEvents_ClickEvent e)
        {
            //if (IsLeftButtonClicked(e.button))
            {
                CloseForm(e.characterID);
            }
        }

        private void axAgent_DblClick(object sender, AxAgentObjects._AgentEvents_DblClickEvent e)
        {
            //if (IsLeftButtonClicked(e.button))
            {
                CloseForm(e.characterID);
            }
        }

        private void frmRunAgent_Shown(object sender, EventArgs e)
        {
            if (this.ClosePending)
            {
                this.Close();
            }
        }

    }//end of class
}
